class StretchRatio {
  static zoomIn := 1.1                 ; the rate of zoom in
  static zoomOut := 0.95               ;
  static normal := 25                  ; the default zoom level
  static max := 30                     ; the max level
  static min := 1                      ; the min level, must be greater than 0
}

zoomTo(g, level) {
  if level = g.ZoomLevel() || level < StretchRatio.min || level > StretchRatio.max
    return

  g.GetPos(&x, &y, &gw, &gh)
  if !g.HasProp('content') {
    g.content := {
      w: gw,
      h: gh
    }
  }
  diff := Abs(level - g.ZoomLevel())

  if level < g.ZoomLevel() {
    if level >= StretchRatio.normal {
      w := g.content.w * (StretchRatio.zoomIn ** (level - StretchRatio.normal))
      h := g.content.h * (StretchRatio.zoomIn ** (level - StretchRatio.normal))
    } else {
      w := gw * (StretchRatio.zoomOut ** diff)
      h := gh * (StretchRatio.zoomOut ** diff)
    }
  } else {
    if level <= StretchRatio.normal {
      w := g.content.w * (StretchRatio.zoomOut ** (StretchRatio.normal - level))
      h := g.content.h * (StretchRatio.zoomOut ** (StretchRatio.normal - level))
    } else {
      w := gw * (StretchRatio.zoomIn ** diff)
      h := gh * (StretchRatio.zoomIn ** diff)
    }
  }
  w := Floor(w), h := Floor(h)
  g.ZoomLevel(level).SizeW(w).SizeH(h)

  g.Move(, , w, h)
}

